package com.aitao.web.response;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分页响应实体类
 *
 * @Author : AiTao
 * @Create : 2021-11-02 19:50
 * @TestClass : {@link test.TestPageResult}
 */
public class PageResult<T> {
    // 当前页
    private Integer currentPage;
    // 每页显示的条数
    private Integer pageSize;
    // 总分页数
    private Integer totalPage = 0;
    // 命中数据条数
    private long total;
    // 当前页起始索引
    private Integer startIndex;
    // 首页索引
    private final Integer firstIndex = 0;
    // 末尾页索引
    private Integer lastIndex;
    // 是否有下一页
    private boolean isNext;
    // 是否有上一页
    private boolean isPrevious;
    // 分页结果
    private List<T> data;
    // 参数集
    public static final Map<Object, Object> PARAMS = new HashMap<>();

    public PageResult() {
        this(1, 10, 0);
    }

    /**
     * @param currentPage 当前页
     * @param pageSize    当前页大小
     * @param total       总数
     */
    public PageResult(Integer currentPage, Integer pageSize, long total) {
        this.currentPage = currentPage;
        putItem("currentPage", this.currentPage);
        this.pageSize = pageSize;
        putItem("pageSize", this.pageSize);
        this.total = total;
        putItem("total", this.total);
        this.startIndex = (this.currentPage - 1) * this.pageSize;
        putItem("startIndex", this.startIndex);
        this.totalPage = Math.toIntExact((this.total + this.pageSize - 1) / this.pageSize);
        putItem("totalPage", this.totalPage);
        this.lastIndex = Math.toIntExact(this.total);
        putItem("lastIndex", this.lastIndex);
        this.isNext = this.currentPage < this.totalPage;
        putItem("isNext", this.isNext);
        this.isPrevious = this.currentPage >= this.totalPage;
        putItem("isPrevious", this.isPrevious);
    }

    @Override
    public String toString() {
        return "PageResult{" +
                "currentPage=" + currentPage +
                ", pageSize=" + pageSize +
                ", totalPage=" + totalPage +
                ", total=" + total +
                ", startIndex=" + startIndex +
                ", isNext=" + isNext +
                ", isPrevious=" + isPrevious +
                ", data=" + data +
                '}';
    }

    /**
     * 自定义属性
     *
     * @param key   键
     * @param value 值
     * @param <K>   键类型
     * @param <V>   值类型
     * @return {@link PageResult<T>}
     */
    public <K, V> PageResult<T> putItem(K key, V value) {
        PARAMS.put(key, value);
        return this;
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public PageResult<T> setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
        return this;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public PageResult<T> setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
        return this;
    }

    public long getTotal() {
        return total;
    }

    public PageResult<T> setTotal(long total) {
        this.total = total;
        return this;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public PageResult<T> setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
        return this;
    }

    public Integer getStartIndex() {
        return startIndex;
    }

    public boolean isNext() {
        return isNext;
    }

    public boolean isPrevious() {
        return isPrevious;
    }

    public List<T> getData() {
        return data;
    }

    public PageResult<T> setData(List<T> data) {
        this.data = data;
        return this;
    }

    public Integer getFirstIndex() {
        return firstIndex;
    }

    public Integer getLastIndex() {
        return lastIndex;
    }

    /**
     * 获取指定页数据
     *
     * @param pageNumber 页码
     */
    public List<T> page(Integer pageNumber) {
        if (pageNumber <= 0 || pageNumber > totalPage) {
            throw new IndexOutOfBoundsException("请输入正确的页码号!");
        }
        int startIndex = (pageNumber - 1) * pageSize, endIndex = startIndex + pageSize;
        return data.subList(startIndex, endIndex);
    }
}
